package util;

/**
 * Deze klasse stelt een coordinaat voor. Een Coordinaat
 * is immutable.
 */
public class Coordinaat {
	
	private int x;
	private int y;
	
	public Coordinaat(int x, int y)
	{
		this.x = x;
		this.y = y;
	}

	public int getX()
	{
		return x;
	}

	public int getY()
	{
		return y;
	}

	/**
	 * Vermenigvuldigt alle componenten met de gegeven factor.
	 * 
	 * @return	return != null
	 */
	public Coordinaat maal(int factor)
	{
		return new Coordinaat(getX() * factor, getY() * factor);
	}

	/**
	 * Telt de componenten van deze en de gegeven coordinaat op
	 * en geeft het resultaat als een nieuwe coordinaat terug.
	 * 
	 * @return	return != null
	 * 
	 * @throws	IllegalCoordinaatException
	 * 			coordinaat == null
	 */
	public Coordinaat plus(Coordinaat coordinaat)
	{
		if(coordinaat == null)
			throw new IllegalCoordinaatException();

		return new Coordinaat(getX() + coordinaat.getX(), getY() + coordinaat.getY());
	}

	public boolean equals(Object object)
	{
		if(object == null)
			return false;

		if(!(object instanceof Coordinaat))
			return false;

		Coordinaat coordinaat = (Coordinaat) object;
		return 
				coordinaat.getX() == this.getX() &&
				coordinaat.getY() == this.getY();
	}

	public String toString()
	{
		return "(" + getX() + ", " + getY() + ")";
	}
	
	/**
	 * Roteert deze coordinaat in de gegeven richting en geeft
	 * het resultaat terug.
	 * 
	 * return	return != null
	 */
	public Coordinaat roteer(Richting richting)
	{
		if(richting == null)
			throw new IllegalRichtingException();
		
		return richting.roteer(this);
	}

	/**
	 * Deze methode trekt van deze coordinaat de gegeven coordinaat af
	 * en geeft het resultaat terug.
	 * 
	 * @return	return = this - coordinaat, return != null
	 * 
	 * @throws	IllegalCoordinaatException
	 * 			coordinaat == null
	 */
	public Coordinaat min(Coordinaat coordinaat) {
		if(coordinaat == null)
			throw new IllegalCoordinaatException();
		
		return plus(new Coordinaat(-coordinaat.getX(), -coordinaat.getY()));
	}
	
	public byte[] toBytes()
	{
		return new byte[] { (byte) getX(), (byte) getY() };
	}
	
	@Override
	public int hashCode()
	{
		return x*97 + y;
	}

	public WindRichting windrichtingNaar(Coordinaat volgend)
	{
		if (this.equals(volgend))
			return null;
		if (this.getX() == volgend.getX())
			return ( (this.getY() < volgend.getY()) ? WindRichting.NOORD : WindRichting.ZUID);
		else if (this.getY() == volgend.getY())
			return ( (this.getX() < volgend.getX()) ? WindRichting.OOST : WindRichting.WEST);
		else
			return null;
	}

	public int afstandTot(Coordinaat coordinaat)
	{
		return Math.abs(this.getX() - coordinaat.getX()) + Math.abs(this.getY() - coordinaat.getY());
	}
}